﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using NJamb.Specifications;
using Stile.Patterns.SelfDescribingPredicates;
using Stile.Patterns.SelfDescribingPredicates.Evaluators;
#endregion

namespace NJamb.Parser.SpecificationBuilders.SubjectIs
{
    public abstract class FluentIs<TSubject, TSpecifies, TNegated> : IFluentIs<TSubject, TSpecifies>,
        INegatableFluentIs<TSubject, TSpecifies, TNegated>,
        ICollaboratingIs<TSubject, TSpecifies>
        where TSpecifies : class, ISpecification
        where TNegated : class, IFluentIs<TSubject, TSpecifies>
    {
        protected FluentIs(ICollaboratingSpecificationBuilder<TSubject, TSpecifies> specificationBuilder, Negated negated)
        {
            SpecificationBuilder = specificationBuilder;
            Negated = negated;
        }

        public Negated Negated { get; private set; }

        public TNegated Not
        {
            get { return FactoryForNegation(SpecificationBuilder, Negated.True); }
        }
        public ICollaboratingSpecificationBuilder<TSubject, TSpecifies> SpecificationBuilder { get; private set; }

        public ICollaboratingIs<TSubject, TSpecifies> Xray
        {
            get { return this; }
        }

        public TSpecifies EqualTo(TSubject subject)
        {
            Evaluator<TSubject, TSubject> evaluator = Expect<TSubject>.ToBeEqualTo(subject, Negated);
            return SpecificationBuilder.Specify(evaluator);
        }

        protected abstract TNegated FactoryForNegation(
            ICollaboratingSpecificationBuilder<TSubject, TSpecifies> specificationBuilder, Negated negated);
    }
}
